package com.christianposta.learnddd.domain.model.voyage;

import java.util.Date;

import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

import com.christianposta.learnddd.domain.model.location.Location;
import com.christianposta.learnddd.domain.shared.ValueObject;

/**
 * A carrier movement is a vessel voyage from one location to another.
 */
public class CarrierMovement implements ValueObject<CarrierMovement>{
	
	private Location departureLocation;
	private Location arrivalLocation;
	private Date departureTime;
	private Date arrivalTime;
	
	// Null object pattern
	public static final CarrierMovement NONE = new CarrierMovement(Location.UNKNOWN, Location.UNKNOWN,
			new Date(0), new Date(0));

	public CarrierMovement(Location departure, Location arrival, Date departureTime,
			Date arrivalTime) {
		Validate.noNullElements(new Object[] {departure, arrival, departureTime, arrivalTime});
		this.departureLocation = departure;
		this.arrivalLocation = arrival;
		this.departureTime = departureTime;
		this.arrivalTime = arrivalTime;
	}

	public boolean sameValueAs(CarrierMovement other) {
		return other != null && new EqualsBuilder().append(this.departureLocation, other.departureLocation)
			.append(this.arrivalLocation, other.arrivalLocation)
			.append(this.departureTime, other.departureTime)
			.append(this.arrivalTime, other.arrivalTime)
			.isEquals();
	}
	
	public Location departureLocation(){
		return this.departureLocation;
	}
	
	public Location arrivalLocation(){
		return this.arrivalLocation;
	}
	
	public Date departureTime(){
		return new Date(this.departureTime.getTime());
	}
	
	public Date arrivalTime(){
		return new Date(this.arrivalTime.getTime());
	}
	
	@Override
	public int hashCode() {

		return new HashCodeBuilder().append(this.departureLocation)
			.append(this.arrivalLocation)
			.append(this.departureTime)
			.append(this.arrivalTime)
			.toHashCode();
	}
	
	@Override
	public boolean equals(Object obj) {
		if(this == obj) return true;
		if(obj == null || obj.getClass() != getClass()) return false;
		
		final CarrierMovement that = (CarrierMovement)obj;
		return sameValueAs(that);
	
	}

	CarrierMovement() {
		// Needed by Hibernate
	}

	// Auto-generated surrogate key
	private Long id;

}
